home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 February / EnigmA AMIGA RUN 15 (1997)(G.R. Edizioni)(IT)[!][issue 1997-02][PLANET CD V].iso / enigma / earcd / varie / uae-0_64.lha / uae-0.6.4 / src / cpuopti.c < prev    next >
C/C++ Source or Header  |  1996-07-23  |  3KB  |  169 lines

  1. /*
  2.  * UAE - The Un*x Amiga Emulator
  3.  *
  4.  * cpuopti.c - Small optimizer for cpu*.s files
  5.  *             Based on work by Tauno Taipaleenmaki
  6.  *
  7.  * Copyright 1996 Bernd Schmidt
  8.  */
  9.  
  10. #include "sysconfig.h"
  11. #include "sysdeps.h"
  12. #include <ctype.h>
  13.  
  14. #include "options.h"
  15.  
  16. struct line {
  17.     struct line *next, *prev;
  18.     int delete;
  19.     char *data;
  20. };
  21.  
  22. struct func {
  23.     struct line *first_line, *last_line;
  24.     int initial_offset;
  25. };
  26.  
  27. static void oops(void)
  28. {
  29.     fprintf(stderr, "Corrupted assembly file!\n");
  30.     abort();
  31. }
  32.  
  33. static char * match(struct line *l, const char *m)
  34. {
  35.     char *str = l->data;
  36.     int len = strlen(m);
  37.     while (isspace(*str))
  38.     str++;
  39.     
  40.     if (strncmp(str, m, strlen(m)) != 0)
  41.     return NULL;
  42.     return str + len;
  43. }
  44.  
  45. static void do_function(struct func *f)
  46. {
  47.     int pops_at_end = 0;
  48.     struct line *l, *fl;
  49.     char *s, *s2;
  50.     int in_pop_area = 1;
  51.     
  52.     f->initial_offset = 0;
  53.     
  54.     l = f->last_line;
  55.     fl = f->first_line;
  56.  
  57.     if (!match(l,"ret"))
  58.     oops();
  59.     l = l->prev;
  60.     
  61.     while (!match(fl, "op_"))
  62.     fl = fl->next;
  63.     fl = fl->next;
  64.     
  65.     s = match(l, "addl $");
  66.     s2 = match(fl, "subl $");
  67.     if (s && s2 && strcmp(s,s2) == 0) {
  68.     int v = 0;
  69.     while (isdigit(*s)) {
  70.         v = v * 10 + (*s) - '0';
  71.         s++;
  72.     }
  73.     if (strcmp(s, ",%esp") == 0) {
  74.         f->initial_offset = v;
  75.         l->delete = 2;
  76.         fl->delete = 3;
  77.         l = l->prev;
  78.         fl = fl->next;
  79.     } else 
  80.         in_pop_area = 0;
  81.     }
  82.     while (in_pop_area) {
  83.     char *popm, *pushm;
  84.     popm = match(l, "popl %");
  85.     pushm = match(fl, "pushl %");
  86.     if (popm && pushm && strcmp(pushm, popm) == 0) {
  87.         pops_at_end++;
  88.         fl->delete = l->delete = 1;
  89.     } else
  90.         in_pop_area = 0;
  91.     l = l->prev;
  92.     fl = fl->next;
  93.     }
  94.     if (f->initial_offset)
  95.     f->initial_offset += 4 * pops_at_end;
  96. }
  97.  
  98. static void output_function(struct func *f)
  99. {
  100.     struct line *l = f->first_line;
  101.     
  102.     while (l) {
  103.     switch (l->delete) {
  104.      case 1:
  105.         break;
  106.      case 0:
  107.         printf("%s\n", l->data);
  108.         break;
  109.      case 2:
  110.         if (f->initial_offset)
  111.         printf("\taddl $%d,%%esp\n", f->initial_offset);
  112.         break;
  113.      case 3:
  114.         if (f->initial_offset)
  115.         printf("\tsubl $%d,%%esp\n", f->initial_offset);
  116.         break;
  117.     }
  118.     l = l->next;
  119.     }
  120. }
  121.  
  122. int main(int argc, char **argv)
  123. {
  124.     char tmp[4096];
  125.  
  126.     for(;;) {
  127.     char *s;
  128.     
  129.     if ((fgets(tmp, 4095, stdin)) == NULL)
  130.         break;
  131.  
  132.     s = strchr (tmp, '\n');
  133.     if (s != NULL)
  134.         *s = 0;
  135.  
  136.     if (strncmp(tmp, ".globl op_", 10) == 0) {
  137.         struct line *first_line = NULL, *prev = NULL;
  138.         struct line **nextp = &first_line;
  139.         struct func f;
  140.         
  141.         do {
  142.         struct line *current;
  143.  
  144.         if (strcmp (tmp, "#APP") != 0 && strcmp (tmp, "#NO_APP") != 0) {
  145.             current = *nextp = (struct line *)malloc(sizeof (struct line));
  146.             nextp = ¤t->next;
  147.             current->prev = prev; prev = current;
  148.             current->next = NULL;
  149.             current->delete = 0;
  150.             current->data = my_strdup (tmp);
  151.         }
  152.         if ((fgets(tmp, 4095, stdin)) == NULL) 
  153.             oops();
  154.         s = strchr (tmp, '\n');
  155.         if (s != NULL)
  156.             *s = 0;
  157.         } while (strncmp (tmp,".Lfe", 4) != 0);
  158.  
  159.         f.first_line = first_line;
  160.         f.last_line = prev;
  161.  
  162.         do_function(&f);
  163.         output_function(&f);
  164.     }
  165.     printf("%s\n", tmp);
  166.     }
  167.     return 0;
  168. }
  169.